package cn.jtfadmin.base.lang.common.controller;


import cn.jtfadmin.base.lang.common.domain.dto.ResultDTO;
import cn.jtfadmin.base.lang.common.domain.entity.IdEntity;
import cn.jtfadmin.base.lang.common.service.BaseService;
import cn.jtfadmin.base.lang.config.ApplicationHolder;
import cn.jtfadmin.base.lang.common.domain.dto.DuplicateCheckPDTO;
import org.springframework.context.ApplicationContext;
import org.springframework.core.convert.ConversionService;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;

/**
 * 公共-数据库字段重复校验
 *
 * @author jtf
 * @since 1.0
 */
@RestController
@Validated
public class DuplicateCheckController {

    /**
     * 校验数据是否在系统中是否存在,暂时支持基本数据
     *
     * @param duplicateCheckPDTO 验证参数
     * @return 判断结果
     */
    @RequestMapping(value = "/common/duplicate/check", method = RequestMethod.GET)
    public ResultDTO<String> doDuplicateCheck(@Valid DuplicateCheckPDTO duplicateCheckPDTO) {
        // 成功数据
        String successData = "该值可用！";
        if (!StringUtils.hasText(duplicateCheckPDTO.getFieldVal())) {
            return ResultDTO.successData(successData);
        }
        // 获取实体管理器和类型转换器, 查询创建器
        ApplicationContext applicationContext = ApplicationHolder.getApplicationContext();
        ConversionService conversionService = applicationContext.getBean(ConversionService.class);
        String[] beanNamesForType = applicationContext.getBeanNamesForType(BaseService.class);
        for (String beanName : beanNamesForType) {
            BaseService bean = applicationContext.getBean(beanName, BaseService.class);
            Class entityClass = bean.getEntityClass();
            if(duplicateCheckPDTO.getTableName().equals(entityClass.getSimpleName())){
                String fieldName = duplicateCheckPDTO.getFieldName();
                Field field = ReflectionUtils.findField(entityClass, fieldName);
                if (Objects.isNull(field)) {
                    return ResultDTO.error("该值不可用，字段不存在！");
                }
                Class<?> fieldType = field.getType();
                Object value = conversionService.convert(duplicateCheckPDTO.getFieldVal(), fieldType);
                List<IdEntity> result = bean.findByField(duplicateCheckPDTO.getFieldName(), value);
                if(result.size()>1 ||
                        (result.size()==1 && !result.iterator().next().getId().equals(duplicateCheckPDTO.getDataId()))
                ){
                    return ResultDTO.error("该值不可用，系统中已存在！");
                }
               return ResultDTO.successData(successData);
            }
        }
        return ResultDTO.error("该值不可用，类型不存在！");

    }

}
